package com.yx.changdao.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yx.changdao.common.entity.*;
import com.yx.changdao.common.enums.Category;
import com.yx.changdao.common.enums.DifficultLevel;
import com.yx.changdao.common.enums.Err;
import com.yx.changdao.common.exception.AlertException;
import com.yx.changdao.common.mapper.ProblemInfoMapper;
import com.yx.changdao.common.utils.ExcelImportExportUtils;
import com.yx.changdao.common.utils.Faster;
import com.yx.changdao.common.utils.SysUtils;
import com.yx.changdao.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * @Description: <br/>
 * 问题信息(在分配之前)
 * <p>
 * <br/>
 * @Auther: xiapeixin
 * @create 2020/05/06 09:51
 */
@Service
public class ProblemInfoServiceImpl extends ServiceImpl<ProblemInfoMapper, ProblemInfo> implements ProblemInfoService {

    @Autowired
    private SysDictService sysDictService;

    @Autowired
    protected CommunityBuildDetailService communityBuildDetail;

    @Autowired
    private CommunityBuildDetailService communityBuildDetailService;

    @Autowired
    private CommunityBuildService communityBuildService;

    @Autowired
    private DepContactGroupService depContactGroupService;

    @Autowired
    private DepWorkerService depWorkerService;

    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private ProblemInfoService problemInfoService;

    @Autowired
    private ProblemService problemService;
    @Autowired
    private ProblemServiceImpl problemServiceImpl;

    /**
     * 问题上报打回记录
     */
    @Autowired
    private ProblemBeatbackService problemBeatbackService;

    @Override
    public void advance(ProblemInfo Info) {

        if (Faster.isNotNull(Info)) {

            Info.setIfRelationBuildDetail(0);

            Info.setCreateTime(null);
            Info.setCreateByName(null);
            Info.setCreateBy(null);

            Info.setUpdateTime(null);
            Info.setUpdateByName(null);
            Info.setUpdateBy(null);

            Info.setIfReport(null);

            Info.setBuildName(null);
            Info.setGridId(null);
            Info.setBuildDetailId(null);

            Info.setContactGroupId(null);
            Info.setContactGroupName(null);
            Info.setContactNames(null);
        }
    }

    @Override
    public boolean saveOrUpdateProblem(ProblemInfo problemInfo, boolean isStrict) throws AlertException {
        //预处理,擦除不允许更新的列;
        advance(problemInfo);

        // 录入和上报部门id
        problemInfo.setReportDepId(SysUtils.currentUser().getDepId());
        // 录入和上报部门名称
        problemInfo.setReportDepName(SysUtils.currentUser().getDepName());

        if (isStrict) {
            if (StringUtils.isNotBlank(problemInfo.getResidentIdcard())
                    && problemInfo.getResidentIdcard().length() != 18) {
                throw new AlertException("身份证号必须为18位");
            }
        }

        //当且仅当 category 值为 自主解决问题类 的时候，可以选择办理难度，且办理难度必填；其他值，如果也传了办理难度，过滤掉
        if (Category.SEF.n().equals(problemInfo.getCategory())) {
            Faster.throwNull(problemInfo.getDifficultLevel(), "办理难度不能为空");
        } else {
            problemInfo.setDifficultLevel(null);
        }

        //根据 build_code unit  door_plate 查询户信息，楼信息 网关信息等，如果没查到，则设置没有关联到户；
        //如果查到了，填充相关户信息，并将 是否关联到户 字段更新成1(已关联)
        CommunityBuildDetail detail = communityBuildDetailService
                .getOneByBuildIdAndUnit(problemInfo.getBuildCode(), problemInfo.getDoorPlate(), problemInfo.getUnit());

        if (Faster.isNotNull(detail)) {
            //关联到户
            problemInfo.setIfRelationBuildDetail(1);

            Map<String, Object> build = communityBuildService.getGridNameByBuildId(problemInfo.getBuildCode());
            problemInfo.setBuildName(build.get("buildName").toString());
            Integer gridId = null == build.get("gridId")?null:Integer.parseInt(String.valueOf(build.get("gridId")));
            problemInfo.setGridId(gridId);

            //户id
            problemInfo.setBuildDetailId(detail.getId());
            DepContactGroup group = depContactGroupService.getById(detail.getContactGroupId());
            if(Faster.isNotNull(group)){
                problemInfo.setContactGroupId(group.getContactGroupId());
                problemInfo.setContactGroupName(group.getGroupName());
                List<DepWorker> workers = depWorkerService.byGroup(group.getContactGroupId());
                // 拼接联户人信息
                if (Faster.IsNotEmpty(workers)) {
                    String contactNames = workers.get(0).getWorkerName();
                    problemInfo.setContact1Name(workers.get(0).getWorkerName());
                    problemInfo.setContact1Phone(workers.get(0).getWorkerPhone());
                    if (2 <= workers.size()) {
                        contactNames = workers.get(0).getWorkerName() + "," + workers.get(1).getWorkerName();
                        problemInfo.setContact2Name(workers.get(1).getWorkerName());
                        problemInfo.setContact2Phone(workers.get(1).getWorkerPhone());
                    }
                    problemInfo.setContactNames(contactNames);
                }
            }
        }else {
            // 编辑保存时，根据上传的 楼编号 单元号 室号 查不到户时的处理
            problemInfo.setIfRelationBuildDetail(0);
            problemInfo.setBuildCode("");
            problemInfo.setBuildName("");
            problemInfo.setGridId(null);
            problemInfo.setBuildDetailId(null);
            problemInfo.setContactGroupId(null);
            problemInfo.setContactGroupName("");
            problemInfo.setContact1Name("");
            problemInfo.setContact1Phone("");
            problemInfo.setContact2Name("");
            problemInfo.setContact2Phone("");
            problemInfo.setContactNames("");
        }
        return saveOrUpdate(problemInfo);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ProblemInfo> checkAndSave(MultipartFile problem) throws AlertException {

        //不合格的
        List<ProblemInfo> failed = new ArrayList<>();

        ExcelImportExportUtils.readExcel(ProblemInfo.class, problem, (pro) -> {

            try {
                if (Faster.isNull(pro)) {
                    return;
                }
//                Faster.throwNotIn(pro.getDifficultLevel(), lev);
//                Faster.throwNotIn(pro.getIndustryCategory(), typ);
//                Faster.throwNotIn(pro.getCategory(), cls);

                pro.setProblemInfoId(null);
                saveOrUpdateProblem(pro, false);

            } catch (Exception e) {

            }
        });

        return failed;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteProblem(Integer id) throws AlertException {

        ProblemInfo problemInfo = getById(id);
        Faster.throwNull(problemInfo, Err.NF_PROBLEM.n());

        if (problemInfo.getIfReport().equals(1) || problemInfo.getIfReport().equals(2)) {
            throw new AlertException("问题已经上报无法删除");
        }

        if(problemInfo.getIfReportManager().equals(1)){
            throw new AlertException("问题已经上报管理员无法删除");
        }

        if (removeById(id)) {
            return problemBeatbackService.removeByProblemId(id);
        }
        return false;
    }


    @Override
    public boolean reportManager(Integer proinfoId) throws AlertException {

        ProblemInfo problemInfo = getById(proinfoId);
        Faster.throwNull(problemInfo, Err.NF_PROBLEM.n());

        if(problemInfo.getIfReportManager().equals(1)){
            throw new AlertException("问题已经上报给管理员");
        }

        //上报检查
        Faster.throwNull(problemInfo.getResidentPhone(), "手机号或者座机号不能为空");
        if (0 == problemInfo.getIfRelationBuildDetail()) {
            throw new AlertException("未关联到户，无法提交上报");
        }
        this.checkProblem(problemInfo);


        problemInfo.setIfReportManager(1);
        return updateById(problemInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean reportBatchManager(List<Integer> proinfoIds) throws AlertException {
        for (Integer id : proinfoIds) {
            reportManager(id);
        }
        return true;
    }

    @Override
    public boolean rejectManager(Integer proinfoId) throws AlertException {
        ProblemInfo problemInfo = getById(proinfoId);
        Faster.throwNull(problemInfo, Err.NF_PROBLEM.n());

        if(!problemInfo.getIfReportManager().equals(1)){
            throw new AlertException("当前不是上报状态");
        }

        if (problemInfo.getIfReport().equals(1) || problemInfo.getIfReport().equals(2)) {
            throw new AlertException("问题已经上报连心办无法打回");
        }

        problemInfo.setIfReportManager(3);

        return updateById(problemInfo);
    }


    @Override
    public boolean report(Integer proId) throws AlertException {
        return executeReport(proId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean reportBatch(List<Integer> proIds) throws AlertException {
        if (!Faster.IsNotEmpty(proIds)) {
            return false;
        }
        for (Integer proId : proIds) {
            executeReport(proId);
        }
        return true;
    }

    boolean executeReport(Integer proId) throws AlertException {
        ProblemInfo problemInfo = this.getById(proId);
        Faster.throwNull(problemInfo, "未查到问题信息");
        Faster.throwNull(problemInfo.getResidentPhone(), "手机号或者座机号不能为空");
        if (0 == problemInfo.getIfRelationBuildDetail()) {
            throw new AlertException("未关联到户，无法提交上报");
        }
        this.checkProblem(problemInfo);
        this.setReportInfo(problemInfo);
        this.updateById(problemInfo);
        return true;
    }

    /**
     * 设置上报信息
     */
    private void setReportInfo(ProblemInfo problem) {
        SysUser sysUser = SysUtils.currentUser();
        Date now = Faster.now();
        problem.setIfReport(1);
        problem.setReportTime(now);
        // 上报部门id
        problem.setReportDepId(sysUser.getDepId());
        // 上报部门名称
        problem.setReportDepName(sysUser.getDepName());
    }

    /**
     * 上报前数据检查
     */
    private void checkProblem(ProblemInfo problem) throws AlertException {

        Faster.throwNull(problem, Err.NF_PROBLEM.n());

        Faster.throwNull(problem.getCategory(), Err.NF_RES_CAT.n());
        Faster.throwNull(problem.getIndustryCategory(), Err.NF_RES_INC.n());

        List<String> cls = sysDictService.getByParent(29);
        List<String> typ = sysDictService.getByParent(17);

        Faster.throwNotIn(problem.getCategory(), cls, "意见建议类别值不合法");
        Faster.throwNotIn(problem.getIndustryCategory(), typ, "意见建议行业类别值不合法");

        Faster.throwNull(problem.getContent(), Err.NF_RES_CON.n());

        Faster.throwNull(problem.getResidentName(), Err.NF_RES_NAME.n());

        Faster.throwNull(problem.getResidentPhone(), Err.NF_RES_PHONE.n());

        Faster.throwNull(problem.getContactGroupId(), Err.NF_RES_GRO.n());

        if (Category.SEF.n().equals(problem.getCategory())) {
            Faster.throwNull(problem.getDifficultLevel(), Err.NF_RES_LEVEL.n());

            List<String> lev = sysDictService.getByParent(33);
            Faster.throwNotIn(problem.getDifficultLevel(), lev, "办里难度值不合法");

        } else {
            if (StringUtils.isNotBlank(problem.getDifficultLevel())) {
                throw new AlertException("非自主解决问题类不可选择办理难度");
            }
        }

        if (1 != problem.getIfRelationBuildDetail()) {
            throw new AlertException("问题信息没有关联到户，不可提交上报");
        }

        if (problem.getIfReport().equals(1) || problem.getIfReport().equals(2)) {
            throw new AlertException("问题已上报或已通过");
        }

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean rejectOrAgreeBatch(List<Integer> proIds, String content, Integer type) throws AlertException {

        for (Integer proId : proIds) {
            ProblemInfo problemInfo = getById(proId);

            Faster.throwNull(problemInfo, Err.NF_PROBLEM.n());

            if (problemInfo.getIfReport().equals(2)) {
                throw new AlertException("该问题上报已经通过");
            }

            ProblemBeatback beatback = new ProblemBeatback();
            beatback.setProblemInfoId(problemInfo.getProblemInfoId());

            beatback.setBeatbackContent(content);

            beatback.setReportTime(problemInfo.getReportTime()); //上报时间

            beatback.setReportStatus(type);
            // 打回或者通过
            problemInfo.setIfReport(type);
            // 如果类型为自主解决类
            if (Category.SEF.n().equals(problemInfo.getCategory()) && type.equals(2)) {
                problemInfo.setIfAssign(1);
                problemInfo.setIfDifficultLevelAllpass(1);

                problemInfo.setDepNames(problemInfo.getReportDepName());
                problemInfo.setIfDifficultLevelReport(1);
                Problem problem = getProblem(problemInfo);
                problemService.save(problem);
            }
            updateById(problemInfo);

            problemBeatbackService.save(beatback);
        }
        return true;
    }

    /**
     * 生成问题实体
     *
     * @param problemInfo
     * @return
     * @throws AlertException
     */
    private Problem getProblem(ProblemInfo problemInfo) throws AlertException {
        Problem problem = new Problem();
        BeanUtils.copyProperties(problemInfo, problem);
        problem.setSubmitterBy(problemInfo.getUpdateBy());
        problem.setSubmitterByName(problemInfo.getCreateByName());
        problem.setSubmitterTime(problemInfo.getCreateTime());
        problem.setCreateBy(SysUtils.currentUserId());
        problem.setCreateByName(SysUtils.currentUserName());
        problem.setCreateTime(new Date());
        problem.setUpdateBy(null);
        problem.setCreateTime(null);
        problem.setUpdateByName(null);
        problem.setAssignTime(new Date());

        problem.setDepId(problemInfo.getReportDepId());
        problem.setDepName(problemInfo.getReportDepName());

        problem.setIfDifficult(0);
        problem.setIfEnd(0);
        problem.setIfDeal(0);
        problem.setDealLimitTime(getDealLimitTime(problemInfo.getDifficultLevel()));
        problem.setIfTimeout(0);
        problem.setIfDeal(0);
        problem.setIfAssess(0);
        problem.setAssessResult(0);

        problem.setDifficultLevelStatus(2);//难度审核通过
        problem.setDifficultLevelPassTime(Faster.now());

        return problem;
    }

    /**
     * 生成逾期时间
     *
     * @param difficultLevel
     * @return
     * @throws AlertException
     */
    private Date getDealLimitTime(String difficultLevel) throws AlertException {
        Calendar cal = Calendar.getInstance(Locale.CHINA);
        Date date;
        if (DifficultLevel.SIMPLE.n().equals(difficultLevel)) {
            date = problemServiceImpl.backDate(cal.getTime(), 3);
        } else if (DifficultLevel.GENERAL.n().equals(difficultLevel)
                || DifficultLevel.STINT.n().equals(difficultLevel)) {
            date = problemServiceImpl.backDate(cal.getTime(), 7);
        } else if (DifficultLevel.HARD.n().equals(difficultLevel)) {
            date = problemServiceImpl.backDate(cal.getTime(), 60);
        } else {
            throw new AlertException("未知办理难度");
        }
        return date;
    }


}